<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222"><meta name="generator" content="Hexo 5.4.2">

  <link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
  <link rel="mask-icon" href="/images/logo.svg" color="#222">

<link rel="stylesheet" href="/css/main.css">



<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" integrity="sha256-HtsXJanqjKTc8vVQjO4YMhiqFoXkfBsjBWcX91T1jr8=" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.1.1/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">

<script class="next-config" data-name="main" type="application/json">{"hostname":"xiaoqingming18.github.io","root":"/","images":"/images","scheme":"Muse","darkmode":false,"version":"8.15.1","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":{"enable":false,"style":null},"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"menu_item":"fadeInDown","post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果：${query}","hits_time":"找到 ${hits} 个搜索结果（用时 ${time} 毫秒）","hits":"找到 ${hits} 个搜索结果"}}</script><script src="/js/config.js"></script>

    <meta name="description" content="事务什么是事务事务是用户定义的一个数据库操作序列，这些操作要么全做，要么全不做，是一个不可分割的工作单位。 一个事务可以是一条或多条SQL语句，也可以是整个程序，但一般情况是一个程序中包含多个事务。 定义事务在SQL中，定义事务的语句一般有三条：  BEGIN TRANSACTION COMMIT ROLLBACK  事务通常以BEGIN TRANSACTION开始，以COMMIT或ROLLBAC">
<meta property="og:type" content="article">
<meta property="og:title" content="数据库原理：数据库恢复技术">
<meta property="og:url" content="http://xiaoqingming18.github.io/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/index.html">
<meta property="og:site_name" content="鸣蜩十七">
<meta property="og:description" content="事务什么是事务事务是用户定义的一个数据库操作序列，这些操作要么全做，要么全不做，是一个不可分割的工作单位。 一个事务可以是一条或多条SQL语句，也可以是整个程序，但一般情况是一个程序中包含多个事务。 定义事务在SQL中，定义事务的语句一般有三条：  BEGIN TRANSACTION COMMIT ROLLBACK  事务通常以BEGIN TRANSACTION开始，以COMMIT或ROLLBAC">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://xiaoqingming18.github.io/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/利用日志文件恢复.png">
<meta property="og:image" content="http://xiaoqingming18.github.io/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/具有检查点的日志文件和重新开始文件.png">
<meta property="og:image" content="http://xiaoqingming18.github.io/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/恢复子系统采取的不同策略.png">
<meta property="article:published_time" content="2023-05-31T10:06:14.000Z">
<meta property="article:modified_time" content="2023-05-31T12:11:32.993Z">
<meta property="article:author" content="鸣蜩十七">
<meta property="article:tag" content="-数据库恢复技术">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://xiaoqingming18.github.io/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/利用日志文件恢复.png">


<link rel="canonical" href="http://xiaoqingming18.github.io/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/">



<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":false,"isPost":true,"lang":"zh-CN","comments":true,"permalink":"http://xiaoqingming18.github.io/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/","path":"2023/05/31/数据库原理：数据库恢复技术/","title":"数据库原理：数据库恢复技术"}</script>

<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>数据库原理：数据库恢复技术 | 鸣蜩十七</title>
  








  <noscript>
    <link rel="stylesheet" href="/css/noscript.css">
  </noscript>

<style>.github-emoji { position: relative; display: inline-block; width: 1.2em; min-height: 1.2em; overflow: hidden; vertical-align: top; color: transparent; }  .github-emoji > span { position: relative; z-index: 10; }  .github-emoji img, .github-emoji .fancybox { margin: 0 !important; padding: 0 !important; border: none !important; outline: none !important; text-decoration: none !important; user-select: none !important; cursor: auto !important; }  .github-emoji img { height: 1.2em !important; width: 1.2em !important; position: absolute !important; left: 50% !important; top: 50% !important; transform: translate(-50%, -50%) !important; user-select: none !important; cursor: auto !important; } .github-emoji-fallback { color: inherit; } .github-emoji-fallback img { opacity: 0 !important; }</style>
</head>

<body itemscope itemtype="http://schema.org/WebPage" class="use-motion">
  <div class="headband"></div>

  <main class="main">
    <div class="column">
      <header class="header" itemscope itemtype="http://schema.org/WPHeader"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏" role="button">
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
        <span class="toggle-line"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <i class="logo-line"></i>
      <p class="site-title">鸣蜩十七</p>
      <i class="logo-line"></i>
    </a>
      <p class="site-subtitle" itemprop="description">鸣蜩十七是和女朋友谈恋爱的日子</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger" aria-label="搜索" role="button">
    </div>
  </div>
</div>



<nav class="site-nav">
  <ul class="main-menu menu"><li class="menu-item menu-item-home"><a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a></li><li class="menu-item menu-item-about"><a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a></li><li class="menu-item menu-item-tags"><a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签</a></li><li class="menu-item menu-item-categories"><a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类</a></li><li class="menu-item menu-item-archives"><a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档</a></li><li class="menu-item menu-item-schedule"><a href="/schedule/" rel="section"><i class="fa fa-calendar fa-fw"></i>日程表</a></li><li class="menu-item menu-item-sitemap"><a href="/sitemap.xml" rel="section"><i class="fa fa-sitemap fa-fw"></i>站点地图</a></li><li class="menu-item menu-item-commonweal"><a href="/404/" rel="section"><i class="fa fa-heartbeat fa-fw"></i>公益 404</a></li>
  </ul>
</nav>




</header>
        
  
  <aside class="sidebar">

    <div class="sidebar-inner sidebar-nav-active sidebar-toc-active">
      <ul class="sidebar-nav">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <div class="sidebar-panel-container">
        <!--noindex-->
        <div class="post-toc-wrap sidebar-panel">
            <div class="post-toc animated"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#%E4%BA%8B%E5%8A%A1"><span class="nav-text">事务</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BB%80%E4%B9%88%E6%98%AF%E4%BA%8B%E5%8A%A1"><span class="nav-text">什么是事务</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%AE%9A%E4%B9%89%E4%BA%8B%E5%8A%A1"><span class="nav-text">定义事务</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BA%8B%E5%8A%A1%E7%9A%84ACID%E7%89%B9%E6%80%A7"><span class="nav-text">事务的ACID特性</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E6%95%85%E9%9A%9C%E7%9A%84%E7%A7%8D%E7%B1%BB"><span class="nav-text">故障的种类</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BA%8B%E5%8A%A1%E5%86%85%E9%83%A8%E7%9A%84%E6%95%85%E9%9A%9C"><span class="nav-text">事务内部的故障</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%B3%BB%E7%BB%9F%E6%95%85%E9%9A%9C"><span class="nav-text">系统故障</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BB%8B%E8%B4%A8%E6%95%85%E9%9A%9C"><span class="nav-text">介质故障</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E8%AE%A1%E7%AE%97%E6%9C%BA%E7%97%85%E6%AF%92"><span class="nav-text">计算机病毒</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%95%85%E9%9A%9C%E6%80%BB%E7%BB%93"><span class="nav-text">故障总结</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E6%81%A2%E5%A4%8D%E7%9A%84%E5%AE%9E%E7%8E%B0%E6%8A%80%E6%9C%AF"><span class="nav-text">恢复的实现技术</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%95%B0%E6%8D%AE%E8%BD%AC%E5%82%A8"><span class="nav-text">数据转储</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E9%9D%99%E6%80%81%E8%BD%AC%E5%82%A8"><span class="nav-text">静态转储</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8A%A8%E6%80%81%E8%BD%AC%E5%82%A8"><span class="nav-text">动态转储</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%B5%B7%E9%87%8F%E8%BD%AC%E5%82%A8%E4%B8%8E%E5%A2%9E%E9%87%8F%E8%BD%AC%E5%82%A8"><span class="nav-text">海量转储与增量转储</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%99%BB%E8%AE%B0%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6"><span class="nav-text">登记日志文件</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6%E7%9A%84%E6%A0%BC%E5%BC%8F%E5%92%8C%E5%86%85%E5%AE%B9"><span class="nav-text">日志文件的格式和内容</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6%E7%9A%84%E4%BD%9C%E7%94%A8"><span class="nav-text">日志文件的作用</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#%E7%99%BB%E8%AE%B0%E6%97%A5%E5%BF%97%E6%96%87%E4%BB%B6-1"><span class="nav-text">登记日志文件</span></a></li></ol></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E6%81%A2%E5%A4%8D%E7%AD%96%E7%95%A5"><span class="nav-text">恢复策略</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BA%8B%E5%8A%A1%E6%95%85%E9%9A%9C%E7%9A%84%E6%81%A2%E5%A4%8D"><span class="nav-text">事务故障的恢复</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E7%B3%BB%E7%BB%9F%E6%95%85%E9%9A%9C%E7%9A%84%E6%81%A2%E5%A4%8D"><span class="nav-text">系统故障的恢复</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E4%BB%8B%E8%B4%A8%E6%95%85%E9%9A%9C%E7%9A%84%E6%81%A2%E5%A4%8D"><span class="nav-text">介质故障的恢复</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E5%85%B7%E6%9C%89%E6%A3%80%E6%9F%A5%E7%82%B9%E7%9A%84%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF"><span class="nav-text">具有检查点的恢复技术</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#%E6%A3%80%E6%9F%A5%E7%82%B9%E8%AE%B0%E5%BD%95%E7%9A%84%E5%86%85%E5%AE%B9"><span class="nav-text">检查点记录的内容</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#%E5%8A%A8%E6%80%81%E7%BB%B4%E6%8A%A4%E6%97%A5%E5%BF%97%E7%9A%84%E6%96%B9%E6%B3%95"><span class="nav-text">动态维护日志的方法</span></a></li></ol></li></ol></div>
        </div>
        <!--/noindex-->

        <div class="site-overview-wrap sidebar-panel">
          <div class="site-author animated" itemprop="author" itemscope itemtype="http://schema.org/Person">
  <p class="site-author-name" itemprop="name">鸣蜩十七</p>
  <div class="site-description" itemprop="description">记录我的学习、生活和恋爱日常</div>
</div>
<div class="site-state-wrap animated">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
        <a href="/archives/">
          <span class="site-state-item-count">43</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
          <a href="/categories/">
        <span class="site-state-item-count">8</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
          <a href="/tags/">
        <span class="site-state-item-count">37</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>

        </div>
      </div>
    </div>

    
  </aside>


    </div>

    <div class="main-inner post posts-expand">


  


<div class="post-block">
  
  

  <article itemscope itemtype="http://schema.org/Article" class="post-content" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://xiaoqingming18.github.io/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.gif">
      <meta itemprop="name" content="鸣蜩十七">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="鸣蜩十七">
      <meta itemprop="description" content="记录我的学习、生活和恋爱日常">
    </span>

    <span hidden itemprop="post" itemscope itemtype="http://schema.org/CreativeWork">
      <meta itemprop="name" content="数据库原理：数据库恢复技术 | 鸣蜩十七">
      <meta itemprop="description" content="">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          数据库原理：数据库恢复技术
        </h1>

        <div class="post-meta-container">
          <div class="post-meta">
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-calendar"></i>
      </span>
      <span class="post-meta-item-text">发表于</span>
      

      <time title="创建时间：2023-05-31 18:06:14 / 修改时间：20:11:32" itemprop="dateCreated datePublished" datetime="2023-05-31T18:06:14+08:00">2023-05-31</time>
    </span>
    <span class="post-meta-item">
      <span class="post-meta-item-icon">
        <i class="far fa-folder"></i>
      </span>
      <span class="post-meta-item-text">分类于</span>
        <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
          <a href="/categories/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86/" itemprop="url" rel="index"><span itemprop="name">-数据库原理</span></a>
        </span>
    </span>

  
</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">
        <h1 id="事务"><a href="#事务" class="headerlink" title="事务"></a>事务</h1><h2 id="什么是事务"><a href="#什么是事务" class="headerlink" title="什么是事务"></a>什么是事务</h2><p><strong>事务</strong>是用户定义的一个数据库操作序列，这些操作要么全做，要么全不做，是一个不可分割的工作单位。</p>
<p>一个事务可以是一条或多条SQL语句，也可以是整个程序，但一般情况是一个程序中包含多个事务。</p>
<h2 id="定义事务"><a href="#定义事务" class="headerlink" title="定义事务"></a>定义事务</h2><p>在SQL中，定义事务的语句一般有三条：</p>
<ol>
<li>BEGIN TRANSACTION</li>
<li>COMMIT</li>
<li>ROLLBACK</li>
</ol>
<p>事务通常以<code>BEGIN TRANSACTION</code>开始，以<code>COMMIT</code>或<code>ROLLBACK</code>结束。其中，<code>COMMIT</code>表示提交，<strong>将事务中所有对数据库的更新写回到磁盘上的物理数据库中去</strong>，此时事务正常结束。<code>ROLLBACK</code>表示回滚，若在事务运行过程中发生意外，事务无法继续运行，<strong>系统便会将事务中所有已完成的操作全部撤回，回滚到事务开始时的状态</strong>。</p>
<h2 id="事务的ACID特性"><a href="#事务的ACID特性" class="headerlink" title="事务的ACID特性"></a>事务的ACID特性</h2><p>事务具有4个特性，分别是<strong>原子性、一致性、隔离性和持续性</strong>。这4个特性简称为<strong>ACID特性</strong>。下面详细解释一下这几个特性。</p>
<ol>
<li>原子性：事务是数据库的逻辑工作单位，事务中包括的所有操作，要么都做，要么都不做。</li>
<li>一致性：事务执行的结果是使数据库从一个一致性状态变为另一个一致性状态。当事务中所有的操作都做完或者都不做时，就是一个一致性状态。当事务执行过程中出现故障，这时数据库就不处于一致性状态了。</li>
<li>隔离性：一个事务的执行不能被其他事务干扰，及一个事务内部操作及使用的数据对其他并行操作的事务是隔离的，并发执行的各个事务之间不能互相干扰。</li>
<li>持续性：也成永久性，指一个事务一旦提交，它对数据库中数据的改变就应该是永久性的，接下来的其他操作或故障不应该对其执行结果有任何影响。</li>
</ol>
<p>事务ACID特性遭到破坏的原因可能有以下几个：</p>
<ol>
<li>多个事务并行运行时，不同事务的操作交叉执行；</li>
<li>事务在运行过程中被强行停止。</li>
</ol>
<p>在第一种情况下，<strong>数据库管理系统必须保证多个事务的交叉运行不影响这些事务的原子性</strong>；</p>
<p>在第二种情况下，<strong>数据库管理系统必须保证被强行终止的事务对数据库和其他事务没有任何影响</strong>。</p>
<p>以上所说的就是<strong>数据库管理系统中恢复机制和并发控制机制的责任</strong>。</p>
<h1 id="故障的种类"><a href="#故障的种类" class="headerlink" title="故障的种类"></a>故障的种类</h1><p>数据库系统中可能会发生各种各样的故障，大致可以分为以下几类</p>
<h2 id="事务内部的故障"><a href="#事务内部的故障" class="headerlink" title="事务内部的故障"></a>事务内部的故障</h2><p>事务内部的故障有的可以是通过事务程序本身发现并处理的，有的是非预期的，不能由事务处理。</p>
<p>先来看可以通过事务程序本身发现的故障，比如从一个账户向另一个账户赚钱，若当前帐户余额小于要转账的金额，便是一个故障，事务程序应当发现并进行回滚（<code>ROLLBACK</code>）操作。</p>
<p><strong>事务内部更多的故障是非预期的，是不能由应用程序处理的。</strong></p>
<p>事务故障意味着事务没有达到预期的终点（<code>COMMIT</code>或显式的<code>ROLLBACK</code>），恢复程序要在不影响其他事务运行的情况下，强行回滚该事务，即<strong>撤销该事务已经作出的任何对数据库的修改</strong>。这类恢复操作称为<strong>事务撤销（UNDO）</strong>。</p>
<h2 id="系统故障"><a href="#系统故障" class="headerlink" title="系统故障"></a>系统故障</h2><p><strong>系统故障是指造成系统停止运转的任何事件，使得系统要重新启动</strong>。（例如硬件错误、操作系统故障和系统断电等）。<strong>这类故障影响正在运行的所有事务，但不破坏数据库</strong>。</p>
<p>系统故障造成数据库不一致状态的原因有两个，一个是未完成事务对数据库的更新可能已写入数据库，二是已提交事务对数据库的更新可能还留在缓冲区没来得及写入数据库。</p>
<p>恢复子系统必须在系统重新启动时让所有非正常结束的事务回滚，强行撤销所有未完成的事务。</p>
<p>系统重新启动后，恢复子系统还需要<strong>重做（REDO）</strong>所有已完成的事务，以将数据库真正恢复到一致状态。</p>
<h2 id="介质故障"><a href="#介质故障" class="headerlink" title="介质故障"></a>介质故障</h2><p>系统故障称为<strong>软故障</strong>，介质故障称为<strong>硬故障</strong>。硬故障指外在故障，如磁盘损坏、磁头碰撞和瞬时强磁场干扰等。这类故障将破坏数据库或部分数据库。</p>
<h2 id="计算机病毒"><a href="#计算机病毒" class="headerlink" title="计算机病毒"></a>计算机病毒</h2><p>计算机病毒是一种人为故障或破坏。</p>
<h2 id="故障总结"><a href="#故障总结" class="headerlink" title="故障总结"></a>故障总结</h2><p><strong>各类故障对数据库的影响有以下两种可能性</strong>：</p>
<ol>
<li>数据库本身被破坏；</li>
<li>数据库本身没被破坏，但数据可能不正确。</li>
</ol>
<h1 id="恢复的实现技术"><a href="#恢复的实现技术" class="headerlink" title="恢复的实现技术"></a>恢复的实现技术</h1><p>恢复的基本原理很简单，用一个词概括就是<strong>冗余</strong>，数据库中任何一部分被破坏或不正确的数据可以根据存储在系统别处的冗余数据来重建。</p>
<p><strong>建立冗余数据最常用的技术就是数据转储和登记日志文件（logging）。</strong>在一个数据库系统中，这两种方法通常是一起使用的。</p>
<h2 id="数据转储"><a href="#数据转储" class="headerlink" title="数据转储"></a>数据转储</h2><p>数据转储是数据库恢复中采用的基本技术。转储即<strong>数据库管理员定期地将整个数据库复制到磁带、磁盘或其他存储介质上保存起来的过程</strong>。这些备用的数据称为<strong>后备副本</strong>或<strong>后援副本</strong>。</p>
<p>当数据库遭到破坏后将后备副本重新装入，<strong>重装后备副本只能将数据库恢复到转储时的状态</strong>，要想恢复到故障发生时的状态，还需要运行自转储成功后的所有更新事务。</p>
<p>转储可分为静态转储和动态转储</p>
<h3 id="静态转储"><a href="#静态转储" class="headerlink" title="静态转储"></a>静态转储</h3><p><strong>静态转储是指在系统中没有运行事务时进行的转储操作</strong>，此时转储得到的一定是一个数据一致性的副本。静态转储简单，但转储必须等待正在运行的用户事务结束后才能进行。同样，新的事务必须等待转储结束后才能执行。显然，<strong>静态转储会降低数据库的可用性</strong>。</p>
<h3 id="动态转储"><a href="#动态转储" class="headerlink" title="动态转储"></a>动态转储</h3><p><strong>动态转储是指在转储期间允许对数据库进行存取或修改</strong>。转储结束后得到的后援副本上的数据并不能保证正确有效。比如，在转储期间的某个时刻$T_c$，系统把数据$A=10$转储到磁带上，而在下一时刻$T_d$，某一事务将A改为200.转储结束后，后备副本上的A已经是过时的数据了。</p>
<p>因此，必须把转储期间各事务对数据库的修改活动登记下来，建立<strong>日志文件</strong>。这样，<strong>后备副本加上日志文件就能把数据库恢复到某一时刻的正确状态</strong>。</p>
<h3 id="海量转储与增量转储"><a href="#海量转储与增量转储" class="headerlink" title="海量转储与增量转储"></a>海量转储与增量转储</h3><p>转储还可以分为海量转储和增量转储两种。海量转储是指每次转储全部数据库，增量转储是指每次只转储上次转储后更新的数据。</p>
<h2 id="登记日志文件"><a href="#登记日志文件" class="headerlink" title="登记日志文件"></a>登记日志文件</h2><h3 id="日志文件的格式和内容"><a href="#日志文件的格式和内容" class="headerlink" title="日志文件的格式和内容"></a>日志文件的格式和内容</h3><p><strong>日志文件是用来记录事务对数据库的更新操作的文件</strong>。日志分为以记录为单位的日志文件和以数据块为单位的日志文件。</p>
<p><strong>以记录为单位的日志文件中需要登记的内容包括：</strong></p>
<ul>
<li>各个事务的开始（<code>BEGIN TRANSACTION</code>）标记；</li>
<li>各个事务的结束（<code>COMMIT</code>或<code>ROOLBACK</code>）标记；</li>
<li>各个事务的所有更新操作。</li>
</ul>
<p>这里每个事务的开始标记、结束标记和更新操作都是日志文件中的一个日志记录。</p>
<p>日志记录的内容主要包括：</p>
<ul>
<li>事务标识（标明是哪个事务）；</li>
<li>操作的类型（插入、删除或修改）；</li>
<li>操作对象（记录内部标识）；</li>
<li>更新前数据的旧值（对插入操作而言，此项为空）；</li>
<li>更喜欢后数据的新值（对删除操作而言，此项为空）。</li>
</ul>
<p><strong>以数据块为单位的日志文件，日志记录的内容包括事务标识和被更新的数据块。</strong>因为将更新前和更新后的整个块都放入日志文件中，操作类型和操作对象等信息都不需要放入日志记录中了。</p>
<h3 id="日志文件的作用"><a href="#日志文件的作用" class="headerlink" title="日志文件的作用"></a>日志文件的作用</h3><p>日志文件在数据库恢复中起着非常重要的作用，<strong>可以用来进行事务故障恢复和系统故障恢复</strong>，并协助后备副本进行截止故障恢复，具体作用如下：</p>
<ol>
<li>事务故障恢复和系统故障恢复必须用日志文件；</li>
<li>在动态转储方式中必须建立日志文件，后备副本和日志文件结合起来才能有效地恢复数据库；</li>
<li>在静态转储方式中也可以建立日志文件，数据库破坏后可以重新装入后备副本把数据库恢复到转储结束时刻的状态，然后利用日志文件把转储后已完成的事务进行重做处理，对故障发生时尚未完成的事务进行撤销处理。这样不必运行那些已完成的事务程序就可以把数据库恢复到故障前某一时刻的正确状态，如下图所示。</li>
</ol>
<p><img src="/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/利用日志文件恢复.png" alt="利用日志文件恢复"></p>
<h3 id="登记日志文件-1"><a href="#登记日志文件-1" class="headerlink" title="登记日志文件"></a>登记日志文件</h3><p>为保证数据库是可恢复的，登记日志文件时必须遵循两条原则：</p>
<ol>
<li>登记的次序严格按照并发事务执行的时间次序。</li>
<li>必须先写日志文件，后写数据库。</li>
</ol>
<h1 id="恢复策略"><a href="#恢复策略" class="headerlink" title="恢复策略"></a>恢复策略</h1><p>当系统运行过程中发生故障，利用数据库后备副本和日志文件就可以将数据库恢复到故障前的某个一致性状态。不同故障其恢复策略和方法也不一样。</p>
<h2 id="事务故障的恢复"><a href="#事务故障的恢复" class="headerlink" title="事务故障的恢复"></a>事务故障的恢复</h2><p>事务故障是事务在运行至终点前被终止，这时恢复子系统应该利用日志文件撤销（UNDO）此事务已对数据库进行的修改。事务故障的恢复是由系统自动完成的，对用户是透明的。</p>
<p>系统的恢复步骤如下：</p>
<ol>
<li>反向扫描日志文件，查找该事务的更新操作。</li>
<li>对该事务的更新操作执行逆操作。</li>
<li>继续反向扫描日志文件，查找该事务的其他更新操作，并做同样处理。</li>
<li>如此处理下去，直至读到此事务的开始标记，事务故障恢复就完成了。</li>
</ol>
<h2 id="系统故障的恢复"><a href="#系统故障的恢复" class="headerlink" title="系统故障的恢复"></a>系统故障的恢复</h2><p>前面已经讲过，系统故障造成数据库不一致状态的原因有两个，一个是未完成事务对数据库的更新可能已写入数据库，二是已提交事务对数据库的更新可能还留在缓冲区没来得及写入数据库。因此，<strong>恢复操作就是要撤销故障发生时未完成的事务，重做已完成的事务</strong>。</p>
<p>系统的恢复步骤如下：</p>
<ol>
<li><p>正向扫描日志文件，找出在故障发生前已经提交的事务，将其事务标识记入重做队列。同时找出故障发生时尚未完成的事务，将其事务标识记入撤销队列。</p>
</li>
<li><p>对撤销队列中的各个事务进行撤销（UNDO）处理。</p>
<p>进行撤销的方法是，反向扫描日志文件，对每个撤销事务的更新操作执行逆操作。</p>
</li>
<li><p>对重做队列中的各个事务进行重做处理。</p>
<p>进行重做处理的方法是：正向扫描日志文件，对每个重做事务重新执行日志文件登记的操作。</p>
</li>
</ol>
<h2 id="介质故障的恢复"><a href="#介质故障的恢复" class="headerlink" title="介质故障的恢复"></a>介质故障的恢复</h2><p>发生介质故障后，磁盘上的物理数据和日志文件被破坏，这是最严重的一种故障，恢复方法是<strong>重装数据库，然后重做已完成的事务</strong>。</p>
<p>具体的恢复步骤如下：</p>
<ol>
<li><p>装入最新的后备副本，使数据库恢复到最近一次转储时的一致性状态。</p>
<p>对于动态转储的数据库副本，还需同时装入转储开始时刻的日志文件副本，利用恢复系统故障的方法（REDO+UNDO），才能将数据库恢复到一致性状态。</p>
</li>
<li><p>装入相应的日志文件副本（转储结束时刻的日志文件副本），重做已完成的事务。</p>
</li>
</ol>
<p>这样就可以将数据库恢复到故障前某一时刻的一致状态了。</p>
<h1 id="具有检查点的恢复技术"><a href="#具有检查点的恢复技术" class="headerlink" title="具有检查点的恢复技术"></a>具有检查点的恢复技术</h1><p>利用日志文件恢复数据库存在一些弊端，比如有些已完成的事务已经将数据写入数据库了，但恢复子系统还是要重做这些事务，并且搜索整个日志文件需要大量的时间。</p>
<p>为了解决上面所说的问题，有发展了<strong>具有检查点的恢复技术</strong>。这种技术在日志文件中增加一类新的记录——<strong>检查点</strong>记录，增加一个重新开始文件，并让恢复子系统在登录日志文件期间动态地维护日志。</p>
<h2 id="检查点记录的内容"><a href="#检查点记录的内容" class="headerlink" title="检查点记录的内容"></a>检查点记录的内容</h2><p>检查点记录的内容包括：</p>
<ul>
<li>建立检查点时刻所有正在执行的事务清单。</li>
<li>这些事务最近一个日志记录的地址</li>
</ul>
<p>重新开始文件用来记录各个检查点在日志文件中的地址，下图说明了建立检查点$C_i$时对应的日志文件和重新开始文件。</p>
<p><img src="/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/具有检查点的日志文件和重新开始文件.png" alt="具有检查点的日志文件和重新开始文件"></p>
<h2 id="动态维护日志的方法"><a href="#动态维护日志的方法" class="headerlink" title="动态维护日志的方法"></a>动态维护日志的方法</h2><p>动态维护日志的方法是，<strong>周期性地执行建立检查点、保存数据库状态的操作</strong>。具体步骤如下：</p>
<ol>
<li>将当前日志缓冲区的所有日志记录写入磁盘的日志文件上。</li>
<li>在日志文件中写入一个检查点记录。</li>
<li>将当前数据缓冲区的所有数据记录写入磁盘的数据库中。</li>
<li>把检查点记录在日志文件中的地址写入一个重新开始文件。</li>
</ol>
<p>恢复子系统可以定期或不定期地建立检查点，保存数据库状态。检查点可以按照预定的一个时间间隔建立，也可以按照某种规则建立检查点。</p>
<p><strong>使用检查点放大可以改善恢复效率</strong>。当事务T在一个检查点之前被提交，T对数据库做的修改一定都已经被写入数据库，写入时间是在这个检查点建立之前或者在这个检查点建立之时。这样，再进行恢复处理时，没有必要对事务T执行重做操作。</p>
<p>系统出现故障时，恢复子系统根据事务的不同状态采取不同的恢复策略，如下图所示：</p>
<p><img src="/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/恢复子系统采取的不同策略.png" alt="恢复子系统采取的不同策略"></p>
<p>其中各时刻代表意义如下：</p>
<ul>
<li>$T_1$：在检查点之前提交——不要重做。</li>
<li>$T_2$：在检查点之前开始执行，在检查点之后故障点之前提交——重做。</li>
<li>$T_3$：在检查点之前开始执行，在故障点时还未完成——撤销。</li>
<li>$T_4$：在检查点之后开始执行，在故障点之前提交——重做。</li>
<li>$T_5$：在检查点之后开始执行，在故障点时还未完成——撤销。</li>
</ul>

    </div>

    
    
    

    <footer class="post-footer">
          <div class="post-tags">
              <a href="/tags/%E6%95%B0%E6%8D%AE%E5%BA%93%E6%81%A2%E5%A4%8D%E6%8A%80%E6%9C%AF/" rel="tag"># -数据库恢复技术</a>
          </div>

        

          <div class="post-nav">
            <div class="post-nav-item">
                <a href="/2023/05/24/Java%EF%BC%9A%E8%BE%93%E5%85%A5%E8%BE%93%E5%87%BA%E6%B5%81/" rel="prev" title="Java：输入输出流">
                  <i class="fa fa-chevron-left"></i> Java：输入输出流
                </a>
            </div>
            <div class="post-nav-item">
                <a href="/2023/05/31/%E6%95%B0%E6%8D%AE%E5%BA%93%E5%8E%9F%E7%90%86%EF%BC%9A%E5%B9%B6%E5%8F%91%E6%8E%A7%E5%88%B6/" rel="next" title="数据库原理：并发控制">
                  数据库原理：并发控制 <i class="fa fa-chevron-right"></i>
                </a>
            </div>
          </div>
    </footer>
  </article>
</div>






</div>
  </main>

  <footer class="footer">
    <div class="footer-inner">


<div class="copyright">
  &copy; 
  <span itemprop="copyrightYear">2023</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">鸣蜩十七</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/muse/" rel="noopener" target="_blank">NexT.Muse</a> 强力驱动
  </div>

    </div>
  </footer>

  
  <div class="toggle sidebar-toggle" role="button">
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
    <span class="toggle-line"></span>
  </div>
  <div class="sidebar-dimmer"></div>
  <div class="back-to-top" role="button" aria-label="返回顶部">
    <i class="fa fa-arrow-up fa-lg"></i>
    <span>0%</span>
  </div>

<noscript>
  <div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>


  
  <script src="https://cdnjs.cloudflare.com/ajax/libs/animejs/3.2.1/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/schemes/muse.js"></script><script src="/js/next-boot.js"></script>

  




  




  

  <script class="next-config" data-name="enableMath" type="application/json">true</script><script class="next-config" data-name="mathjax" type="application/json">{"enable":true,"tags":"none","js":{"url":"https://cdnjs.cloudflare.com/ajax/libs/mathjax/3.2.2/es5/tex-mml-chtml.js","integrity":"sha256-MASABpB4tYktI2Oitl4t+78w/lyA+D7b/s9GEP0JOGI="}}</script>
<script src="/js/third-party/math/mathjax.js"></script>



</body>
</html>
